// 闭包：可以捕获其所在环境的匿名函数
// 1.匿名函数
// 2.保存为变量，作为参数
// 3.可在一个地方创建闭包，然后在另一个上下文中调用闭包来完成运算
// 4.可以从其定义的作用域捕获值
// 闭包捕获环境区别于与函数
// 闭包捕获环境值的方式：1.取得所有权：fnOnce，2.可变借用：fnMut，3.不可变借用fn
// move关键字：在参数列表前使用move关键字，可以强制闭包取得他所使用过的环境值的所有权，当将闭包传递给新线程以移动数据使其归新线程所有时这个技术很管用。

fn main() {
    let p = 10;
    {
        println!("{}", p); // 作用域也可以取到环境里边的参数
    };
    fn add(x: u32) -> u32 {
        // 函数
        // println!("{}", p); // 不能使用环境上的参数
        return x + 1;
    }
    let add1 = |x: u32| -> u32 { 
        // 闭包
        println!("{}", p); // 闭包可以捕获环境的参数
        return x + 1 
    };
    let add2 = |x| x; // 没有定义类型那么就要使用一次
    let a = add2(1); // 第一次定义就会定义好闭包的类型
    // let a1 = add2(String::from("value")); // 这里就要用第一次定义的类型否则会报错
    println!("hello world！");
}
